'use client';
import * as React from 'react';
import { useControlled } from '@base-ui-components/utils/useControlled';
import { useStableCallback } from '@base-ui-components/utils/useStableCallback';
import { MenuRadioGroupContext } from './MenuRadioGroupContext';
import { useRenderElement } from '../../utils/useRenderElement';
import type { BaseUIComponentProps } from '../../utils/types';
import type { MenuRoot } from '../root/MenuRoot';

/**
 * Groups related radio items.
 * Renders a `<div>` element.
 *
 * Documentation: [Base UI Menu](https://base-ui.com/react/components/menu)
 */
export const MenuRadioGroup = React.memo(
  React.forwardRef(function MenuRadioGroup(
    componentProps: MenuRadioGroup.Props,
    forwardedRef: React.ForwardedRef<Element>,
  ) {
    const {
      render,
      className,
      value: valueProp,
      defaultValue,
      onValueChange: onValueChangeProp,
      disabled = false,
      ...elementProps
    } = componentProps;

    const [value, setValueUnwrapped] = useControlled({
      controlled: valueProp,
      default: defaultValue,
      name: 'MenuRadioGroup',
    });

    const onValueChange = useStableCallback(onValueChangeProp);

    const setValue = useStableCallback(
      (newValue: any, eventDetails: MenuRadioGroup.ChangeEventDetails) => {
        onValueChange?.(newValue, eventDetails);

        if (eventDetails.isCanceled) {
          return;
        }

        setValueUnwrapped(newValue);
      },
    );

    const state = React.useMemo(() => ({ disabled }), [disabled]);

    const element = useRenderElement('div', componentProps, {
      state,
      ref: forwardedRef,
      props: {
        role: 'group',
        'aria-disabled': disabled || undefined,
        ...elementProps,
      },
    });

    const context: MenuRadioGroupContext = React.useMemo(
      () => ({
        value,
        setValue,
        disabled,
      }),
      [value, setValue, disabled],
    );

    return (
      <MenuRadioGroupContext.Provider value={context}>{element}</MenuRadioGroupContext.Provider>
    );
  }),
);

export interface MenuRadioGroupProps extends BaseUIComponentProps<'div', MenuRadioGroup.State> {
  /**
   * The content of the component.
   */
  children?: React.ReactNode;
  /**
   * The controlled value of the radio item that should be currently selected.
   *
   * To render an uncontrolled radio group, use the `defaultValue` prop instead.
   */
  value?: any;
  /**
   * The uncontrolled value of the radio item that should be initially selected.
   *
   * To render a controlled radio group, use the `value` prop instead.
   */
  defaultValue?: any;
  /**
   * Function called when the selected value changes.
   */
  onValueChange?: (value: any, eventDetails: MenuRadioGroup.ChangeEventDetails) => void;
  /**
   * Whether the component should ignore user interaction.
   *
   * @default false
   */
  disabled?: boolean;
}

export type MenuRadioGroupState = {
  disabled: boolean;
};

export type MenuRadioGroupChangeEventReason = MenuRoot.ChangeEventReason;
export type MenuRadioGroupChangeEventDetails = MenuRoot.ChangeEventDetails;

export namespace MenuRadioGroup {
  export type Props = MenuRadioGroupProps;
  export type State = MenuRadioGroupState;
  export type ChangeEventReason = MenuRadioGroupChangeEventReason;
  export type ChangeEventDetails = MenuRadioGroupChangeEventDetails;
}
